package 
{
	import Box2D.Dynamics.b2Body;
	
	import com.util.Camera;
	
	import flash.display.Sprite;
	
	import levelloader.TiledMap;
	
	import starling.animation.Juggler;
	import starling.core.Starling;
	import starling.events.Event;

	public class World extends GameObject
	{
		public var firstPlane:GameObject;
		public var enemies:GameObject;
		public var secondPlane:GameObject;
		public var thirdPlane:GameObject;
		public var worldObjects:GameObject;
		public var _bunky:Bunky;										
		private var mJuggler:Juggler;
		private var mHeroJuggler:Juggler;
		
		//private var mySound:Sound = new Sound();
		
		private static var _world:World;

		private var TMX:TiledMap;		
		
		public function World()
		{
			super();
			_world = this;						
			this.addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);

			TMX = new TiledMap();
			TMX.addEventListener(starling.events.Event.COMPLETE, onDataLoaded);					
			TMX.loadMap();			
		}

		private function onDataLoaded():void
		{
				
		}
		
		/*		private static var _loader:URLLoader;
		public function loadMapXML(file:String, listener:Function):void
		{
		_loader = new URLLoader();
		_listener = listener;
		_loader.addEventListener(flash.events.Event.COMPLETE, onMapXMLLoaded);
		_loader.load(new URLRequest(file));
		}
		
		private function onMapXMLLoaded(event:flash.events.Event):void
		{									
		loadMapData();	
		}
		*/		

		public function getTMXTileMap():TiledMap
		{
			return TMX;
		}
		
		private function onAddedToStage(event:Event):void
		{
			this.removeEventListener(starling.events.Event.ADDED_TO_STAGE, null);
					
			_bunky = new Bunky();						
						
			thirdPlane = new GameLayer(this, Assets.BACKGROUND, 1);						
			secondPlane = new GameLayer(this, Assets.MIDLAYER, 1);			
			firstPlane = new GameLayer(this, Assets.PLATFORM, 1);
			enemies = new DynamicLayer(this, Assets.ENEMIES, 1);
			worldObjects = new DynamicLayer(this, Assets.ANIMATIONS, 1, false);			
			var collec:DynamicLayer = new DynamicLayer(this, Assets.COLLECTABLES, 1, false);
			
			mJuggler = new Juggler();
			mHeroJuggler = new Juggler();
						
			addChild(thirdPlane);
			addChild(secondPlane);
			addChild(worldObjects);
			addChild(firstPlane);
			addChild(collec);
			addChild(enemies);
			addChild(_bunky);									
			//this.addEventListener(starling.events.TouchEvent.TOUCH, onTouched);
			this.addEventListener(EnemySpawnEvent.ENEMY_SPAWN, onEnemySpawnTick);
			this.addEventListener(BunkyDeathEvent.BUNKY_DEATH, onBunkyDeath);									
			//trace("Game height: " + this.height);
		}
						
		private function onBunkyDeath(e:Event):void
		{	
			//dispatchEvent(new GameModeChangedEvent(GameModeChangedEvent.GAME_LEVEL_QUIT, true));
			(this.parent as Game).onLevelEnd();
		}
		
		public function canHeroJump():Boolean
		{
			return (this.parent as Game).canHeroJump();
		}

		public function isHeroStuck():Boolean
		{
			return (this.parent as Game).isHeroStuck();
		}

		private function onEnemySpawnTick(e:EnemySpawnEvent):void
		{
			enemySpawn(e._spawnCount);
		}
				
		private var spawnTime:Number = 0;
		private var enemySpawnDelay:Number = 5;		
		public override function onEnterFrame(dt:Number):void
		{		
			//update all the gameobjects
			var child:GameObject;
			for(var idx:int = 0; idx < this.numChildren; ++idx)
			{			
				 child = this.getChildAt(idx) as GameObject;
				
				if(child != null)
					child.onEnterFrame(dt);
			}	
			
			//do collision detection and invoke gameobjects
			//that need to respond to any collision
			collisionmanager.updateCollision();

			if(canHeroJump() && !isHeroStuck())
				mHeroJuggler.advanceTime(dt*1.5);
				
			mJuggler.advanceTime(dt*1.5);
		}
		
/*		public function get camera():StarlingCameraFocus
		{
			return (this.parent as Game).camera;
		}
*/		
		public function get camera():Camera
		{
			return (this.parent as Game).camera;
		}
		
		private function enemySpawn(spawnCount:uint):void
		{
			var obj:tinku = ObjectPool.getObject(tinku) as tinku;
			if(obj != null)
				addChild(obj);
		}
		
		
		public static function get juggler():Juggler { return _world ? _world.mJuggler: null; }
		
		public function get heroJuggler():Juggler { return mHeroJuggler; }
		
		public override function dispose():void 
		{			
			super.dispose();			
			juggler.purge();
			mHeroJuggler.purge();
			_world = null;			
		}
		
		public function createPhysBody(x:Number, y:Number, width:Number, height:Number, isDynamic:Boolean, name:String=null):b2Body
		{
			var game:Game = this.parent as Game;			
			return game.createBox(x, y, width, height, isDynamic, name);						
		}
		
		public function removePhysBody(physBody:b2Body):void
		{
			var game:Game = this.parent as Game;			
			return game.removePhysBody(physBody);						
		}

		public static function isOffScreen(obj:GameObject):Boolean
		{
			return (obj.x <= -obj.width || obj.x >= Starling.current.stage.stageWidth);
		}

		public function pause(flag:Boolean):void
		{
			var child:GameObject;
			for(var idx:int = 0; idx < this.numChildren; ++idx)
			{			
				child = this.getChildAt(idx) as GameObject;
				
				if(child != null && !(child is HUD))
				{
					if(flag)
						child.alpha = 0.7;
					else
						child.alpha = 1;
				}					
			}					
		}
	}	
}